// 参考 https://openlayers.org/en/latest/examples/print-to-scale.html

import { getPointResolution } from "ol/proj";

import html2canvas from "html2canvas";
import { jsPDF } from "jspdf";

// v 纵向, h 横向
const dims = {
  a0_v: [1189, 841],
  a1_V: [841, 594],
  a2_v: [594, 420],
  a3_v: [420, 297],
  a4_v: [297, 210],
  a5_v: [210, 148],
  a0_h: [841, 1189],
  a1_h: [594, 841],
  a2_h: [420, 594],
  a3_h: [297, 420],
  a4_h: [210, 297],
  a5_h: [148, 210],
};

// export options for html2canvase.
// See: https://html2canvas.hertzen.com/configuration
const exportOptions = {
  allowTaint: true,
  useCORS: true,
  ignoreElements: function (element) {
    const className = element.className || "";
    return !(
      className.indexOf("ol-control") === -1 ||
      className.indexOf("ol-scale") > -1 ||
      (className.indexOf("ol-attribution") > -1 &&
        className.indexOf("ol-uncollapsible"))
    );
  },
};

export function mapping(map, options) {
  // exportButton.disabled = true;
  // document.body.style.cursor = 'progress';

  console.log("制图中。。。开始制图");

  const pageSettings = options.pageSettings;
  const resolution = Number(options.resolution);
  const scale = Number(options.scale);
  const dim = dims[pageSettings];
  const width = Math.round((dim[0] * resolution) / 25.4);
  const height = Math.round((dim[1] * resolution) / 25.4);
  const viewResolution = map.getView().getResolution();
  const scaleResolution =
    scale /
    getPointResolution(
      map.getView().getProjection(),
      resolution / 25.4,
      map.getView().getCenter()
    );

  map.once("rendercomplete", function () {
    console.log("制图中。。。地图加载");

    exportOptions.width = width;
    exportOptions.height = height;
    html2canvas(map.getViewport(), exportOptions).then(function (canvas) {
      // const pdf = new jsPDF('landscape', undefined, pageSettings);
      const pdf = new jsPDF();
      pdf.addImage(
        canvas.toDataURL("image/jpeg"),
        "JPEG",
        0,
        0,
        dim[0],
        dim[1]
      );

      console.log("制图中。。。画布");

      pdf.autoPrint();

      pdf.save("map.pdf");

      // Reset original map size
      // scaleLine.setDpi();
      map.getTargetElement().style.width = "";
      map.getTargetElement().style.height = "";
      map.updateSize();
      map.getView().setResolution(viewResolution);
      exportButton.disabled = false;
      document.body.style.cursor = "auto";
    });
  });

  // Set print size
  // scaleLine.setDpi(resolution);
  map.getTargetElement().style.width = width + "px";
  map.getTargetElement().style.height = height + "px";
  map.updateSize();
  map.getView().setResolution(scaleResolution);
}

export function mappingImg(map) {
  map.once("rendercomplete", function () {
    const mapCanvas = document.createElement("canvas");
    const size = map.getSize();
    mapCanvas.width = size[0];
    mapCanvas.height = size[1];
    const mapContext = mapCanvas.getContext("2d");
    Array.prototype.forEach.call(
      document.querySelectorAll(".ol-layer canvas"),
      function (canvas) {
        if (canvas.width > 0) {
          const opacity = canvas.parentNode.style.opacity;
          mapContext.globalAlpha = opacity === "" ? 1 : Number(opacity);
          const transform = canvas.style.transform;
          // Get the transform parameters from the style's transform matrix
          const matrix = transform
            .match(/^matrix\(([^\(]*)\)$/)[1]
            .split(",")
            .map(Number);
          // Apply the transform to the export map context
          CanvasRenderingContext2D.prototype.setTransform.apply(
            mapContext,
            matrix
          );
          mapContext.drawImage(canvas, 0, 0);
        }
      }
    );

    if (navigator.msSaveBlob) {
      // link download attribute does not work on MS browsers
      navigator.msSaveBlob(mapCanvas.msToBlob(), "map.png");
    } else {
      var iframe =
        "<iframe width='100%' height='100%' src='" +
        mapCanvas.toDataURL() +
        "'></iframe>";
      var x = window.open();
      x.document.open();
      x.document.write(iframe);
      x.document.close();
    }
  });
  map.renderSync();
}
